// This is the preload script. 
// It runs before the web page is loaded into the browser window.
// It has access to both DOM APIs and Node.js environment.
// You can expose Node.js features to the renderer process here in a controlled way.

// 安全地导入模块，确保在不同环境中都能工作
let contextBridge, ipcRenderer, fs, path;

// 检查是否在Electron环境中
try {
  const electron = require('electron');
  contextBridge = electron.contextBridge;
  ipcRenderer = electron.ipcRenderer;

  // 尝试导入Node.js模块
  try {
    fs = require('fs');
    path = require('path');
    console.log('Node.js modules loaded successfully');
  } catch (err) {
    console.warn('Failed to load Node.js modules:', err);
  }
} catch (err) {
  console.warn('Not in Electron environment, mocking APIs for browser environment');
  // 在浏览器环境中，提供模拟实现
  contextBridge = {
    exposeInMainWorld: (key, api) => {
      window[key] = api;
    }
  };
}

console.log('Preload script loaded.');

// Store listeners safely to allow removal
const listeners = {};

// 检查是否可以暴露API
if (contextBridge) {
  // 暴露一个安全的方法给渲染进程，只包含我们允许的功能
  contextBridge.exposeInMainWorld('electronAPI', {
    // 只暴露 invoke 方法，增加安全性
    invoke: (channel, ...args) => {
      // 定义允许的通道列表，防止调用任意通道
      const allowedChannels = [
        'handle-export-project', 
        'handle-export-for-miniblink', 
        'handle-export-source', 
        'handle-export-miniblink',
        'handle-export-miniblink-vue3',
        'show-save-dialog',
        'show-open-dialog',
        'save-file', 
        'save-html-file',
        'open-directory', 
        'open-file',
        // 添加构建相关的IPC通道
        'get-npm-cache-path',
        'check-build-environment',
        'build-vue-project',
        'save-blob-to-temp',
        'clean-temp-files',
        'open-folder',
        'open-build-output-folder'
      ];
      if (ipcRenderer && allowedChannels.includes(channel)) {
        return ipcRenderer.invoke(channel, ...args);
      } else {
        console.error(`IPC channel "${channel}" is not allowed or not available.`);
        return Promise.reject(new Error(`IPC channel "${channel}" is not allowed or not available.`));
      }
    },
    // Expose a safe version of ipcRenderer.on
    on: (channel, callback) => {
      if (!ipcRenderer) {
        console.error('ipcRenderer not available for on() method');
        return () => {};
      }
      
      const allowedReceiveChannels = [
        'export-progress',
        'export-status-update',  // 添加导出状态更新通道
        'build-progress'         // 添加构建进度通道
      ];
      if (!allowedReceiveChannels.includes(channel)) {
        console.error(`IPC receive channel "${channel}" is not allowed.`);
        return () => {};
      }
      // Wrap the callback to ensure it's always a function
      const wrappedCallback = (event, ...args) => {
        if (typeof callback === 'function') {
            callback(...args);
        } else {
            console.error('Provided callback is not a function for channel:', channel)
        }
      };
      // Store the wrapped callback to allow removal later
      listeners[channel] = listeners[channel] || [];
      listeners[channel].push({ original: callback, wrapped: wrappedCallback });
      ipcRenderer.on(channel, wrappedCallback);

      // Return a function to remove this specific listener
      return () => {
        if (ipcRenderer) {
          ipcRenderer.removeListener(channel, wrappedCallback);
          // Also remove from our tracked listeners
          if (listeners[channel]) {
            listeners[channel] = listeners[channel].filter(l => l.original !== callback);
            if (listeners[channel].length === 0) {
              delete listeners[channel];
            }
          }
        }
      };
    },
  }); 

  // 提供更安全的Node.js API访问
  if (ipcRenderer) {
    contextBridge.exposeInMainWorld('electron', {
      ipcRenderer: {
        invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
        send: (channel, ...args) => ipcRenderer.send(channel, ...args),
        on: (channel, func) => {
          const subscription = (event, ...args) => func(...args);
          ipcRenderer.on(channel, subscription);
          return () => {
            ipcRenderer.removeListener(channel, subscription);
          };
        },
        once: (channel, func) => {
          ipcRenderer.once(channel, (event, ...args) => func(...args));
        },
      },
    });
  }

  // 暴露Node.js模块
  if (fs && path) {
    contextBridge.exposeInMainWorld('nodeAPI', {
      fs: {
        readFileSync: (filePath, options) => {
          try {
            return fs.readFileSync(filePath, options);
          } catch (error) {
            console.error('Error reading file:', error);
            throw error;
          }
        },
        writeFileSync: (filePath, data, options) => {
          try {
            return fs.writeFileSync(filePath, data, options);
          } catch (error) {
            console.error('Error writing file:', error);
            throw error;
          }
        },
        existsSync: (path) => fs.existsSync(path),
        mkdirSync: (path, options) => {
          try {
            return fs.mkdirSync(path, options);
          } catch (error) {
            console.error('Error creating directory:', error);
            throw error;
          }
        },
      },
      path: {
        join: (...args) => path.join(...args),
        dirname: (p) => path.dirname(p),
        basename: (p, ext) => path.basename(p, ext),
        extname: (p) => path.extname(p),
      },
      process: {
        cwd: () => process.cwd(),
        env: process.env,
        platform: process.platform,
      },
    });
  } else {
    // 提供一个模拟版本的API，以避免在浏览器环境中出错
    contextBridge.exposeInMainWorld('nodeAPI', {
      fs: {
        readFileSync: () => { throw new Error('fs.readFileSync is not available in browser environment'); },
        writeFileSync: () => { throw new Error('fs.writeFileSync is not available in browser environment'); },
        existsSync: () => false,
        mkdirSync: () => { throw new Error('fs.mkdirSync is not available in browser environment'); },
      },
      path: {
        join: (...args) => args.join('/'),
        dirname: (p) => p.split('/').slice(0, -1).join('/'),
        basename: (p) => p.split('/').pop(),
        extname: (p) => {
          const base = p.split('/').pop();
          return base.includes('.') ? '.' + base.split('.').pop() : '';
        },
      },
      process: {
        cwd: () => '/',
        env: {},
        platform: 'browser',
      },
    });
  }
} else {
  console.warn('contextBridge not available, cannot expose APIs');
} 